package com.spikything.video {
	
	import flash.display.BlendMode;
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.display.Sprite;
	import flash.display.Bitmap;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	
	import com.spikything.video.events.VideoEvent;
	import com.irisnation.ing.formula1.Globals;

	public class VolumeSlider extends Sprite {
		
		private const 	SCRUBBER_DAMPING:Number 	= 2;
		private const 	ALPHA_DAMPING 	:Number 	= 4;
		private const 	ROLLOFF_MARGIN 	:Number 	= 15;
		private const 	SCRUBBER_ALPHA 	:Number 	= .8;
		private const 	SCRUBBER_WIDTH 	:Number 	= 10;
		private const 	SCRUBBER_HEIGHT :Number 	= 103;
		private const 	SCRUBBER_ROUND 	:Number 	= 10;
		private const 	SCRUBBER_Y 		:Number 	= 10;
		private const 	PADDING 		:Number 	= 5;
		private const 	INSET 			:Number 	= 6;
		private var 	mouseIsDown 	:Boolean;
		private var 	scrubber 		:Sprite;
		private var 	maskClip 		:Sprite;
		private var 	beacon 			:EventDispatcher;
		private var 	_position 		:Number;
		private var 	_alpha 			:Number 	= 0;
		
		[Embed(source='../../../../assets/gfx/player_volume_slider.png')] private var bgClass :Class; // 23x125
		[Embed(source='../../../../assets/gfx/nodule.png')] private var noduleClass :Class; // 11x11
		private var 	nodule 			:Sprite;
		
		public function VolumeSlider (beacon:EventDispatcher, x:Number=0, y:Number=0) {
			
			this.beacon = beacon;
			this.x = x;
			this.y = y;
			visible = false;
			alpha = 0;
			
			this.blendMode = BlendMode.LAYER;
			
			addChild(new bgClass() as Bitmap);
			maskClip = Sprite(addChild(new Sprite() as DisplayObject));
			maskClip.graphics.beginFill(0);
			maskClip.graphics.drawRoundRect(INSET, INSET, SCRUBBER_WIDTH, SCRUBBER_HEIGHT+PADDING*2, SCRUBBER_ROUND, SCRUBBER_ROUND);
			
			scrubber = new Sprite();
			scrubber.graphics.beginFill(Globals.SCRUBBER_COLOUR, SCRUBBER_ALPHA);
			scrubber.graphics.drawRect(INSET, 0, SCRUBBER_WIDTH, SCRUBBER_HEIGHT+PADDING);
			addChild(scrubber);
			scrubber.mask = maskClip;
			scrubber.height = _position = 0;
			
			nodule = new Sprite();
			nodule.addChild(new noduleClass() as Bitmap);
			addChild(nodule);
			nodule.x = INSET;
			nodule.y = SCRUBBER_HEIGHT/2;
			
			buttonMode = true;
			mouseChildren = false;
			
			beacon.addEventListener(VideoEvent.INFO_VOLUME, update);
			beacon.addEventListener(VideoEvent.DO_OPEN_VOL_SLIDER, show);
			beacon.addEventListener(VideoEvent.DO_CLOSE_VOL_SLIDER, hide);
			addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
			addEventListener(Event.ENTER_FRAME, oef);
			
		}
		
		private function show (e:Event=null):void {
			visible = true;
			_alpha = 1;
		}
		
		private function hide (e:Event=null):void {
			_alpha = 0;
		}
		
		private function update (ve:VideoEvent):void {
			_position = ve.volume;
		}
		
		private function mouseMove (e:MouseEvent):void {
			if (!mouseIsDown) return;
			var ve:VideoEvent = new VideoEvent(VideoEvent.INFO_VOLUME);
			var vs:VideoEvent = new VideoEvent(VideoEvent.DO_SETVOLUME);
			ve.volume = vs.volume = getPos(mouseY);
			update(ve);
			beacon.dispatchEvent(vs);
		}

		private function mouseDown (e:MouseEvent):void {
			mouseIsDown = true;
			beacon.removeEventListener(VideoEvent.INFO_VOLUME, update);
			stage.addEventListener(MouseEvent.MOUSE_UP, mouseUp);
			stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
			mouseMove(e);
		}

		private function mouseUp (e:MouseEvent):void {
			mouseIsDown = false;
			stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUp);
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
			var ve:VideoEvent = new VideoEvent(VideoEvent.INFO_VOLUME);
			var vs:VideoEvent = new VideoEvent(VideoEvent.DO_SETVOLUME);
			ve.volume = vs.volume = getPos(mouseY);
			beacon.addEventListener(VideoEvent.INFO_VOLUME, update);
			beacon.dispatchEvent(vs);
			update(ve);
		}
		
		private function oef (e:Event):void {
			var offset:Number = Math.floor(nodule.height/2);
			nodule.y += (SCRUBBER_HEIGHT+SCRUBBER_Y-(SCRUBBER_Y-offset + _position * SCRUBBER_HEIGHT)-nodule.y)/SCRUBBER_DAMPING;
			scrubber.y = nodule.y + offset - 2;
			scrubber.height = SCRUBBER_HEIGHT+SCRUBBER_Y - scrubber.y + INSET;
			alpha += (_alpha-alpha)/ALPHA_DAMPING;
			if (alpha<.1) visible = false;
			if (mouseX>width+ROLLOFF_MARGIN || mouseX<-ROLLOFF_MARGIN || mouseY>height+2+ROLLOFF_MARGIN*2 || mouseY<-ROLLOFF_MARGIN) hide();
		}
		
		private function getPos (where:Number):Number {
			return 1-Math.max(Math.min(1, ((where-SCRUBBER_Y)/SCRUBBER_HEIGHT)), 0);
		}
		
	}
	
}